﻿using GameView.Models;
using GameView.Services.Comment;
using GameView.Views;
using Microsoft.Extensions.DependencyInjection;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace GameView.Comment
{
    public static class ExtentHelper
    {
        private static JsonSerializerOptions options = new JsonSerializerOptions
        {
            DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull  // 忽略序列化时的 null（不影响反序列化）
        };

        public static T GetService<T>()
        {
            return App.ServiceProvider.GetRequiredService<T>();
        }

        public static object GetService(Type type)
        {
            return App.ServiceProvider.GetRequiredService(type);
        }

        public static bool IsNullOrEmpty(this string value)
        {
            return string.IsNullOrEmpty(value);
        }

        public static bool IsNullOrEmpty<T>(this List<T> value)
        {
            if (value == null || value.Count <= 0)
                return true;
            return false;
        }

        public static Type GetViewByRoutePath(this string pmss)
        {
            Type res = null;
            switch (pmss)
            {
                case "RechargeRecord":
                    res = typeof(RechargeView);
                    break;

                case "WithdrawalRecords":
                    res = typeof(WithdrawalView);
                    break;

                case "PlayerRecharge":
                    res = typeof(FastRehcargeView);
                    break;

                case "MerchantRecharge":
                    res = typeof(RechargeToMView);
                    break;

                case "StatisticalOverview":
                    res = typeof(StatisticsByProjectsView);
                    break;
            }
            return res;
        }

        #region HTTP

        public static bool SetToken(this HttpClient httpClient)
        {
            if (httpClient == null)
                return false;
            if (!string.IsNullOrEmpty(StaticValues.Token))
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", StaticValues.Token);
            else
                return false;
            return true;
        }

        public static async Task<ApiResponse<int>> DeleteData<TParam>(this string url, TParam param)
            where TParam : class
        {
            try
            {
                var json = JsonSerializer.Serialize(param);
                using (var client = new HttpClient())
                using (var request = new HttpRequestMessage(HttpMethod.Delete, url))
                using (request.Content = new StringContent(json, Encoding.UTF8, "application/json"))
                {
                    if (!client.SetToken())
                        return new() { Errors = "您的密钥缺失！" };
                    var httpResponse = await client.SendAsync(request).ConfigureAwait(false);
                    //var responseBody = await httpResponse.Content.ReadFromJsonAsync<ApiResponse<int>>();
                    var responseBodyStr = await httpResponse.Content.ReadAsStringAsync();
                    if (responseBodyStr.IsNullOrEmpty())
                        return new ApiResponse<int>() { Errors = "服务未响应！" };
                    var res = JSON.Deserialize<ApiResponse<object>>(responseBodyStr);
                    if (res.StatusCode == 200)
                        return new ApiResponse<int>(res);
                    else
                        return new ApiResponse<int>() { Errors = JSON.Serialize(res.Errors) };
                }
            }
            catch (Exception ex)
            {
                return new ApiResponse<int>() { Errors = ex.Message };
            }
        }

        public static async Task<ApiResponse<TResult>> AddNewAsync<TParam, TResult>(this string url, TParam param)
         where TParam : class
        {
            try
            {
                var json = JsonSerializer.Serialize(param);
                using (var client = new HttpClient())
                using (var request = new HttpRequestMessage(HttpMethod.Post, url))
                using (request.Content = new StringContent(json, Encoding.UTF8, "application/json"))
                {
                    if (!client.SetToken())
                        return new() { Errors = "您的密钥缺失！" };
                    var httpResponse = await client.SendAsync(request).ConfigureAwait(false);
                    var responseBodyStr = await httpResponse.Content.ReadAsStringAsync();
                    var res = JSON.Deserialize<ApiResponse<object>>(responseBodyStr);
                    if (res.StatusCode == 200)
                        return new ApiResponse<TResult>(res);
                    else
                        return new ApiResponse<TResult>() { Errors = JSON.Serialize(res.Errors) };
                }
            }
            catch (Exception ex)
            {
                return new ApiResponse<TResult>() { Errors = ex.Message };
            }
        }

        public static async Task<ApiResponse<bool>> AddNewAsync<TParam>(this string url, TParam param)
           where TParam : class
        {
            return await url.AddNewAsync<TParam, bool>(param);
        }

        public static async Task<ApiResponse<TResult>> PutAsync<TResult, TParam>(this string url, TParam param)
          where TParam : class
        {
            try
            {
                var json = JSON.Serialize(param);
                using (var client = new HttpClient())
                using (var request = new HttpRequestMessage(HttpMethod.Put, url))
                using (request.Content = new StringContent(json, Encoding.UTF8, "application/json"))
                {
                    if (!client.SetToken())
                        return new() { Errors = "您的密钥缺失！" };
                    var httpResponse = await client.SendAsync(request).ConfigureAwait(false);
                    var responseBodyStr = await httpResponse.Content.ReadAsStringAsync();
                    var res = JSON.Deserialize<ApiResponse<object>>(responseBodyStr);
                    if (res.StatusCode == 200)
                        return new ApiResponse<TResult>(res);
                    else
                        return new ApiResponse<TResult>() { Errors = JSON.Serialize(res.Errors) };
                }
            }
            catch (Exception ex)
            {
                return new ApiResponse<TResult>() { Errors = ex.Message };
            }
        }

        public static async Task<ApiResponse<TResult>> PostAsync<TResult, TParam>(this string url, TParam param)
          where TParam : class
        {
            try
            {
                var json = JsonSerializer.Serialize(param);
                using (var client = new HttpClient())
                using (var request = new HttpRequestMessage(HttpMethod.Post, url))
                using (request.Content = new StringContent(json, Encoding.UTF8, "application/json"))
                {
                    if (!client.SetToken())
                        return new() { Errors = "您的密钥缺失！" };
                    var httpResponse = await client.SendAsync(request).ConfigureAwait(false);
                    var responseBodyStr = await httpResponse.Content.ReadAsStringAsync();

                    var res = JSON.Deserialize<ApiResponse<object>>(responseBodyStr);
                    var sa = res.Data.ToString();
                    if (res.StatusCode == 200)
                        return new ApiResponse<TResult>(res);
                    else
                        return new ApiResponse<TResult>() { Errors = JSON.Serialize(res.Errors) };
                }
            }
            catch (Exception ex)
            {
                return new ApiResponse<TResult>() { Errors = ex.Message };
            }
        }

        public static async Task<ApiResponse<TResult>> GetAsync<TResult, TParam>(this string url, TParam param = null)
  where TParam : class
        {
            try
            {
                // 1. 将参数转换为查询字符串
                var queryString = System.Web.HttpUtility.ParseQueryString(string.Empty);
                var fullUrl = url;
                if (param != null)
                {
                    var properties = typeof(TParam).GetProperties();
                    foreach (var prop in properties)
                    {
                        var value = prop.GetValue(param)?.ToString();
                        if (value != null)
                        {
                            queryString.Add(prop.Name, value);
                        }
                    }
                    fullUrl = $"{url}?{queryString}";
                }
                // 2. 使用静态HttpClient或IHttpClientFactory
                using var client = new HttpClient();

                // 3. 添加Token
                if (!client.SetToken())
                    return new() { Errors = "您的密钥缺失！" };

                // 4. 发送请求
                using var response = await client.GetAsync(fullUrl).ConfigureAwait(false);
                if (response.StatusCode == HttpStatusCode.Forbidden)
                {
                    return new ApiResponse<TResult>
                    {
                        StatusCode = (int)response.StatusCode,
                        Errors = $"您的登录信息已过期请重新登录！"
                    };
                }
                if (response.StatusCode == HttpStatusCode.Unauthorized)
                {
                    return new ApiResponse<TResult>
                    {
                        StatusCode = (int)response.StatusCode,
                        Errors = $"您无权限操作此项！"
                    };
                }
                if (response.StatusCode == HttpStatusCode.InternalServerError)
                {
                    return new ApiResponse<TResult>
                    {
                        StatusCode = (int)response.StatusCode,
                        Errors = $"服务器内部错误：\n{await response.Content.ReadAsStringAsync()}"
                    };
                }
                // 5. 检查状态码
                if (!response.IsSuccessStatusCode)
                {
                    return new ApiResponse<TResult>
                    {
                        StatusCode = (int)response.StatusCode,
                        Errors = $"HTTP Error: {(int)response.StatusCode} {response.ReasonPhrase}"
                    };
                }

                // 6. 反序列化（带配置）
                var options = new JsonSerializerOptions
                {
                    PropertyNameCaseInsensitive = true
                };

                return await response.Content.ReadFromJsonAsync<ApiResponse<TResult>>(options)
                       ?? new ApiResponse<TResult> { Errors = "反序列化响应失败" };
            }
            catch (HttpRequestException ex)
            {
                return new ApiResponse<TResult>() { Errors = $"网络请求失败: {ex.Message}" };
            }
            catch (JsonException ex)
            {
                return new ApiResponse<TResult>() { Errors = $"JSON解析失败: {ex.Message}" };
            }
            catch (Exception ex)
            {
                return new ApiResponse<TResult>() { Errors = $"未知错误: {ex.Message}" };
            }
        }

        #endregion HTTP

        public static string ToStringFormat(this DateTime time)
        {
            return time.ToString("yyyy-MM-dd HH:mm");
        }

        public static string ToStringFormatShort(this DateTime time)
        {
            return time.ToString("yyyy-MM-dd");
        }

        public static string ReBuildTIme(this string Date, string time)
        {
            if (Date.Contains(" "))
                Date = Date.Remove(Date.IndexOf(" "));
            Date = $"{Date} {time}";
            return Date;
        }

        public static string ToStringMax(this DateTime time)
        {
            var dt = new DateTime(time.Year, time.Month, time.Day, 23, 59, 59);
            return dt.ToString("yyyy-MM-dd HH:mm:ss");
        }

        public static string ToStringMin(this DateTime time)
        {
            var dt = new DateTime(time.Year, time.Month, time.Day, 00, 00, 01);
            return time.ToString("yyyy-MM-dd HH:mm:ss");
        }

        public static DateTime? TryConvertToDateTime(this string str)
        {
            if (str.IsNullOrEmpty())
                return null;
            if (DateTime.TryParse(str, out var dt))
                return dt;
            return null;
        }

        private static Dictionary<int, string> dic = new Dictionary<int, string>()
        {
            [1101] = "客服",
            [1102] = "商人",
            [4001] = "增加",
            [4002] = "扣除",
            [6001] = "在线",
            [6002] = "离线",
            [2501] = "未读",
            [2502] = "已读",
            [2001] = "待付款",
            [2002] = "账号错误",
            [2003] = "已付款",
            [2004] = "已屏蔽",
            [2005] = "待审核",
            [2006] = "已通过",
            [5001] = "支付宝",
            [5002] = "微信",
            [5003] = "银联",
            [5004] = "其他",
            [3001] = "成功",
            [3002] = "失败",
            [3003] = "取消",
            [3004] = "已提交",
            [7002] = "商人",
            [7003] = "玩家",
            [3701] = "登录",
            [3702] = "登出",
            [3703] = "查询",
            [3704] = "新增",
            [3705] = "修改",
            [3706] = "删除",
            [3707] = "其他",
            [0] = "未知"
        };

        public static string GetDisplay(this int key)
        {
            if (!dic.TryGetValue(key, out var str))
                return "";
            return str;
        }
    }
}